package com.baomidou.springwind.pojo;

import com.baomidou.springwind.entity.NetworkNode;
import com.baomidou.springwind.utils.CityUtil;

import java.math.BigDecimal;
import java.util.*;

/**
 * 城市配送象限分组对象构造
 *
 * @Author demo
 * @Date 2017-8-6
 */
public class TransportGroupBuilder {

    private Set<NetworkNode> nodes;
    private BigDecimal centerCoordinateX;
    private BigDecimal centerCoordinateY;

    public TransportGroupBuilder(List<NetworkNode> nodeList) {
        this.nodes = new HashSet<NetworkNode>(nodeList);
    }

    private void initCenterCoordinate() {
        BigDecimal totalX = new BigDecimal(0);
        BigDecimal totalY = new BigDecimal(0);
        BigDecimal totalAmount = new BigDecimal(0);
        for (NetworkNode node : nodes) {
            totalX = totalX.add(node.getCoordinateX().multiply(node.getAmount()));
            totalY = totalY.add(node.getCoordinateY().multiply(node.getAmount()));
            totalAmount = totalAmount.add(node.getAmount());
        }
        centerCoordinateX = totalX.divide(totalAmount, 10, BigDecimal.ROUND_HALF_EVEN);
        centerCoordinateY = totalY.divide(totalAmount, 10, BigDecimal.ROUND_HALF_EVEN);
    }

    public CityTransportGroup build() {
        CityTransportGroup group = new CityTransportGroup();
        group.setOtherGroup(buildOtherGroup());
        initCenterCoordinate();
        group.setCenterGroup(buildCenterGroup());
        group.setFirstGroup(buildFirstGroup());
        group.setSecondGroup(buildSecondGroup());
        group.setThirdGroup(buildThirdGroup());
        group.setFourthGroup(buildFourthGroup());
        return group;
    }

    private List<NetworkNode> buildOtherGroup() {
        TreeSet<NetworkNode> sortedMap = new TreeSet<NetworkNode>(new Comparator<NetworkNode>() {
            @Override
            public int compare(NetworkNode o1, NetworkNode o2) {
                return o1.getAmount().compareTo(o2.getAmount());
            }
        });
        sortedMap.addAll(nodes);
        List<NetworkNode> group = new ArrayList<NetworkNode>();
        group.add(sortedMap.pollLast());
        group.add(sortedMap.pollLast());
        nodes.removeAll(group);//必须删除排除点
        return group;
    }

    private List<NetworkNode> buildCenterGroup() {
        Map<Double, NetworkNode> distanceMap = new TreeMap<Double, NetworkNode>(new Comparator<Double>() {
            @Override
            public int compare(Double o1, Double o2) {
                if (o1.equals(o2)) {
                    return 0;
                }
                return o1 - o2 > 0 ? 1 : -1;
            }
        });
        for (NetworkNode node : nodes) {
            double distance = CityUtil.getDistance(centerCoordinateX.doubleValue(), centerCoordinateY.doubleValue(), node.getCoordinateX().doubleValue(), node.getCoordinateY().doubleValue());
            distanceMap.put(distance, node);
        }
        //默认取前4个相近的
        List<NetworkNode> group = new ArrayList<NetworkNode>(distanceMap.values()).subList(0, nodes.size() / 5);
        nodes.removeAll(group);//必须删除中心点
        return group;
    }

    /**
     * 构造第一象限的组
     * 业务点的经度小于中心点精度，纬度大于中心点纬度
     *
     * @return
     */
    private List<NetworkNode> buildFirstGroup() {
        List<NetworkNode> group = new ArrayList<NetworkNode>();
        for (NetworkNode node : nodes) {
            if (node.getCoordinateX().compareTo(centerCoordinateX) < 0
                    && node.getCoordinateY().compareTo(centerCoordinateY) > 0) {
                group.add(node);
            }
        }
        nodes.removeAll(group);
        return group;
    }

    /**
     * 构造第二象限的组
     * 业务点的经度大于中心点精度，纬度大于中心点纬度
     *
     * @return
     */
    private List<NetworkNode> buildSecondGroup() {
        List<NetworkNode> group = new ArrayList<NetworkNode>();
        for (NetworkNode node : nodes) {
            if (node.getCoordinateX().compareTo(centerCoordinateX) > 0
                    && node.getCoordinateY().compareTo(centerCoordinateY) > 0) {
                group.add(node);
            }
        }
        nodes.removeAll(group);
        return group;
    }

    /**
     * 构造第三象限的组
     * 业务点的经度大于中心点精度，纬度小于中心点纬度
     *
     * @return
     */
    private List<NetworkNode> buildThirdGroup() {
        List<NetworkNode> group = new ArrayList<NetworkNode>();
        for (NetworkNode node : nodes) {
            if (node.getCoordinateX().compareTo(centerCoordinateX) > 0
                    && node.getCoordinateY().compareTo(centerCoordinateY) < 0) {
                group.add(node);
            }
        }
        nodes.removeAll(group);
        return group;
    }

    /**
     * 构造第四象限的组
     * 业务点的经度小于中心点精度，纬度小于中心点纬度
     *
     * @return
     */
    private List<NetworkNode> buildFourthGroup() {
        List<NetworkNode> group = new ArrayList<NetworkNode>();
        for (NetworkNode node : nodes) {
            if (node.getCoordinateX().compareTo(centerCoordinateX) < 0
                    && node.getCoordinateY().compareTo(centerCoordinateY) < 0) {
                group.add(node);
            }
        }
        nodes.removeAll(group);
        return group;
    }
}
